#include "server.h"

int main(int argc, char *argv[]){
	//服务器端，客户端套接字
	static int clnt_sock;
	//指令字符串
	char cmdinfo[STR_BUF_SZ], pidfile[FNAME_LEN]={0};
	//接收次数，接受长度
	int recv_cnt,recv_len;
	//服务器端,客户端IPv4地址结构
	struct sockaddr_in serv_addr,clnt_addr,data_addr;
	//线程号
	pthread_t tid;
	//epoll监视计数器
	int i;
	char buf[STR_BUF_SZ];
	int str_len;
	//用户信息存储
	auth auth_n;
	//发生变化的文件描述符
	volatile int tfd;

	//经认证客户端信息列表
	struct epoll_event event;
	//发生变化的套接字数
	int event_cnt;

	if(argc != 2){
		printf("Usage: %s start | stop | status\n", argv[0]);
		exit(1);
	}

	//获取pid文件名
	ftpd_pid_file(pidfile);

	if(!strcmp("status", argv[1])){
		if(file_exists(pidfile)){
			puts("Ftpd deamon is running.");
		}else{
			puts("Ftpd deamon is not running.");
		}

		return 0;
	}

	if(!strcmp("stop", argv[1])){
		if(file_exists(pidfile)){
			char pids[20];
			FILE *pfp=fopen(pidfile, "r");

			if(pfp == NULL){
				puts("Open ftpd deamon pid file failed");
				set_log_to_file("Open ftpd deamon pid file failed");

				return 1;
			}
			fgets(pids, 20, pfp);
			fclose(pfp);
			if(cancel_deamon((pid_t)atoi(pids))){
				puts("Stop ftpd deamon successfully.");
				//删除pid文件成功
				if(remove(pidfile) == -1){
					fprintf(stderr, "unlink pidfile %s failed.", pidfile);
				}

				return 0;
			}else{
				puts("Stop ftpd deamon failed.");
				set_log_to_file("Stop ftpd deamon failed.");
				return 3;
			}
		}else{
			puts("Ftpd deamon is not running.");
		}
	}

	//系统检测，64位系统
	system_detect();

	//读取配置文件
	if(!load_config(CONF_FILE)){
		error_handling("load config file failed.");
	}

	//读取用户信息
	if(!load_user(conf_ptr->user)){
		error_handling("load user file failed.");
	}

	//服务器端按下Crtl + C
	key_control_c_register();

	//建立套接字
	serv_sock=socket(AF_INET, SOCK_STREAM, 0);
	quick_restart(serv_sock);
	if(serv_sock == -1)
		socket_error();

	/**
	 * 服务器端控制连接地址初始化
	 * 采用TCP/IP IPv4地址族
	 */
	memset(&serv_addr, 0, sizeof(serv_addr));
	serv_addr.sin_family = AF_INET;
	serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
	serv_addr.sin_port = htons(conf_ptr->port);

	//绑定并监听端口号
	if(bind(serv_sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) == -1){
		if(!strcmp("start", argv[1])){
			if(file_exists(pidfile)){
				puts("Ftpd deamon is already started.");
				return 0;
			}
		}else{
			bind_error();
		}
	}
	if(listen(serv_sock, conf_ptr->client) == -1)
		listen_error();

	if(!auth_init(&auth_list)){
		error_handling("create user table failed.");
	}

	//初始化epoll池
	epoll_init(conf_ptr->client);
	event.events = EPOLLIN;
	event.data.fd = serv_sock;
	epoll_ctl(epfd, EPOLL_CTL_ADD, serv_sock, &event);
	if(DEBUG){
		printf("Server Socket: %d \n", serv_sock);
		printf("Epoll Fd: %d \n", epfd);
	}

	if(!set_deamon()){
		fprintf(stderr, "Ftpd deamon start...\t\t[Failed].\n");
		exit(3);
	}

	while(true){
		event_cnt=epoll_wait(epfd, ep_events, conf_ptr->client, -1);

		if(event_cnt == -1){
			printf("epoll_wait() error! \n");
			break;
		}

		if(DEBUG){
			printf("epoll_wait %d events. \n", event_cnt);
		}
		for(i=0; i<event_cnt; i++){
			tfd = ep_events[i].data.fd;

			if(tfd == serv_sock){
				server_handler(tfd);
			}else{
				//多线程实现多用户同时访问
				pthread_mutex_t mutex;

				set_locked(&mutex);
				pthread_create(&tid, NULL, client_handler, (void *)&tfd);
				set_unlocked(&mutex);
				pthread_detach(tid);
				//client_handler((void *)&tfd);
			}
		}
	}

	printf("program should never goes here! \n");

	return 1;
}
